package org.linlinjava.litemall.core.util;

import org.apache.commons.lang3.StringUtils;
import org.linlinjava.litemall.core.inventory.InventoryService;
import org.linlinjava.litemall.db.util.WechatUtil;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * @author wj
 * @date 2021/9/28 14:24
 * 对于库存的增删和刷新库存
 *  redis格式：  KEY：门店/云仓 - 类型 -库存类型 - 商品 - 具体商品规格；VALUE： 库存数量
 *              KEY：门店/云仓 - 类型 -库存类型 - 商品；VALUE： 库存数量
 *
 *
 *  参数总览：   storeId 门店/云仓id
 *              type  类型 0-门店 1-云仓
 *              inventoryType  库存类型  0-门店 1-链条锁 2-衣柜锁 3-云仓
 *              goodsId  商品id
 *              specId   商品规格id
 */
@Component
public class InventoryUtil {

    public static Integer TYPE_STORE = 0;
    public static Integer TYPE_CLOUD = 1;
    public static Integer STOCK_STORE = 0;
    public static Integer STOCK_SOFTCHAIN = 1;
    public static Integer STOCK_CABINET = 2;
    //云仓
    public static Integer STOCK_CLOUD = 3;

    @Resource
    private InventoryService inventoryService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private WechatUtil wechatUtil;

    /**
     * 增加库存
     * @param storeId 门店/云仓id
     * @param type  类型 0-门店 1-云仓
     * @param inventoryType  库存类型  0-门店 1-链条锁 2-衣柜锁 3-云仓
     * @param goodsId  商品id
     * @param specId   商品规格id
     * @return 增加后的库存
     */
    public Integer add(Integer storeId,Integer type,Integer inventoryType,Integer goodsId,Integer specId){
        Integer value=get(storeId,type,inventoryType,goodsId,specId);
        String key=InventoryStringAssembleUtil.assembleKey(storeId,type,inventoryType,goodsId,specId);
        value+=1;
        stringRedisTemplate.opsForValue().set(key,value.toString());
        //如果增加的是某个规格的库存，需要同时增加商品库存
        if(specId!=null){
            Integer goodsValue=get(storeId,type,inventoryType,goodsId,null);
            String goodsKey=InventoryStringAssembleUtil.assembleKey(storeId,type,inventoryType,goodsId,null);
            goodsValue=goodsValue==null?0:goodsValue;
            goodsValue+=1;
            stringRedisTemplate.opsForValue().set(goodsKey,goodsValue.toString());
            //发送到货通知
            wechatUtil.sendSubscribeMessage(storeId.longValue(),goodsId.longValue(),specId.longValue(),1);
        }
        return value;
    }

    /**
     * 增加库存-多个
     * @param storeId 门店/云仓id
     * @param type  类型 0-门店 1-云仓
     * @param inventoryType  库存类型  0-门店 1-链条锁 2-衣柜锁 3-云仓
     * @param goodsId  商品id
     * @param specId   商品规格id
     * @param number   数量
     * @return 增加后的库存
     */
    public Integer addBatch(Integer storeId,Integer type,Integer inventoryType,Integer goodsId,Integer specId,Integer number){
        if(number<=0){
            return -1;
        }
        Integer value=get(storeId,type,inventoryType,goodsId,specId);
        String key=InventoryStringAssembleUtil.assembleKey(storeId,type,inventoryType,goodsId,specId);
        Integer newValue=value+number;
        stringRedisTemplate.opsForValue().set(key,newValue.toString());
        //如果增加的是某个规格的库存，需要同时增加商品库存
        if(specId!=null){
            Integer goodsValue=get(storeId,type,inventoryType,goodsId,null);
            String goodsKey=InventoryStringAssembleUtil.assembleKey(storeId,type,inventoryType,goodsId,null);
            goodsValue=goodsValue==null?0:goodsValue;
            Integer goodsNewValue=goodsValue+number;
            stringRedisTemplate.opsForValue().set(goodsKey,goodsNewValue.toString());
            //发送到货通知
            wechatUtil.sendSubscribeMessage(storeId.longValue(),goodsId.longValue(),specId.longValue(),number);
        }
        return newValue;
    }

    /**
     * 减少库存
     * @param storeId 门店/云仓id
     * @param type  类型 0-门店 1-云仓
     * @param inventoryType  库存类型  0-门店 1-链条锁 2-衣柜锁 3-云仓
     * @param goodsId  商品id
     * @param specId   商品规格id
     * @return 减少后的库存  如果返回-1 则代表库存已经为0
     */
    public Integer remove(Integer storeId,Integer type,Integer inventoryType,Integer goodsId,Integer specId){
        Integer value=get(storeId,type,inventoryType,goodsId,specId);
        String key=InventoryStringAssembleUtil.assembleKey(storeId,type,inventoryType,goodsId,specId);
        if(value==0){
            return -1;
        }
        value-=1;
        stringRedisTemplate.opsForValue().set(key,value.toString());
        //如果减少的是某个规格的库存，需要同时减少商品库存
        if(specId!=null){
            Integer goodsValue=get(storeId,type,inventoryType,goodsId,null);
            if(goodsValue==0){
                return -1;
            }
            String goodsKey=InventoryStringAssembleUtil.assembleKey(storeId,type,inventoryType,goodsId,null);
            goodsValue-=1;
            stringRedisTemplate.opsForValue().set(goodsKey,goodsValue.toString());
        }
        return value;
    }

    /**
     * 减少库存-多个
     * @param storeId 门店/云仓id
     * @param type  类型 0-门店 1-云仓
     * @param inventoryType  库存类型  0-门店 1-链条锁 2-衣柜锁 3-云仓
     * @param goodsId  商品id
     * @param specId   商品规格id
     * @param number   数量
     * @return 减少后的库存  如果返回-1 则代表库存已经为0
     */
    public Integer removeBatch(Integer storeId,Integer type,Integer inventoryType,Integer goodsId,Integer specId,Integer number){
        Integer value=get(storeId,type,inventoryType,goodsId,specId);
        String key=InventoryStringAssembleUtil.assembleKey(storeId,type,inventoryType,goodsId,specId);
        if(number<0||value==0||number>value){
            return -1;
        }
        Integer newValue=value-number;
        stringRedisTemplate.opsForValue().set(key,newValue.toString());
        //如果减少的是某个规格的库存，需要同时减少商品库存
        if(specId!=null){
            Integer goodsValue=get(storeId,type,inventoryType,goodsId,null);
            if(goodsValue==0||number>goodsValue){
                return -1;
            }
            String goodsKey=InventoryStringAssembleUtil.assembleKey(storeId,type,inventoryType,goodsId,null);
            Integer goodsNewValue=goodsValue-number;
            stringRedisTemplate.opsForValue().set(goodsKey,goodsNewValue.toString());
        }
        return newValue;
    }

    /**
     * 刷新库存
     * @param storeId 门店/云仓id
     * @param type  类型 0-门店 1-云仓
     */
    public void refresh(Integer storeId,Integer type){
        inventoryService.getStoreInventoryByStoreId(storeId,type);
    }

    /**
     * 获取库存
     * @param storeId 门店/云仓id
     * @param type  类型 0-门店 1-云仓
     * @param inventoryType  库存类型  0-门店 1-链条锁 2-衣柜锁 3-云仓
     * @param goodsId  商品id
     * @param specId   商品规格id
     */
    public Integer get(Integer storeId,Integer type,Integer inventoryType,Integer goodsId,Integer specId){
        String key=InventoryStringAssembleUtil.assembleKey(storeId,type,inventoryType,goodsId,specId);
        String value = stringRedisTemplate.opsForValue().get(key);
                if(StringUtils.isNotBlank(value)){
                    return Integer.parseInt(value);
                }
                else{
                    refresh(storeId,type);
                    String refreshValue=stringRedisTemplate.opsForValue().get(key);
                    if(StringUtils.isNotBlank(refreshValue)){
                        return Integer.parseInt(refreshValue);
                    }
                    else{
                        //设置短期缓存  防止缓存穿透
                        stringRedisTemplate.opsForValue().set(key,"0",2, TimeUnit.MINUTES);
                        return 0;
                    }
                }
    }




}
